/**
 * @author chentl
 * @version V1.0
 * @Project leisurely
 * @Title TimeServerHandler.java
 * @Description 时间服务器
 * @Package com.echo.ioex.io.server.handler
 * @date 2020/9/15 1:07 下午
 * @Copyright: 陈泰来の学习档案 .
 */
package com.echo.ioex.bio.server;

import com.echo.ioex.bio.server.handler.TimeServerHandler;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 同步阻塞IO Server端的思路：
 * 1 服务端启动一个 ServerSocket 监听指定端口号
 * 2 轮询是否有客户端连接，此时阻塞在客户端连接前
 * 3 当有客户端连接时，启动新线程实现run方法处理客户端发来的消息。

 * 优点： 并发量很小时编程简单。其他几乎没有什么优点
 * 弊端： 缺乏弹性伸缩能力，当客户端并发访问量增加后，服务端的线程数和客户端并发数呈现1:1的正比关系。JVM中线程数膨胀会直接导致堆栈溢出、
 * 创建新线程失败、最终导致宕机。
 * @author chentl
 * @version V1.0
 * @Project leisurely
 * @Title TimeServer.java
 * @Description 同步阻塞 I/O 的 TimeServer端
 * @Package com.echo.ioex.io.server
 * @date 2020/9/15 1:08 下午
 * @Copyright: 陈泰来の学习档案 .
 */
@Slf4j
public class TimeServer {

    public static void main(String[] args) throws IOException {
        //默认端口
        int port = 9999;
        if (args != null && args.length > 0) {
            try {

            } catch (NumberFormatException e) {
                //采用默认值
                log.info("没有参数，则选择默认配置 port :{}", port);
            }
        }

        //启动服务
        ServerSocket server = null;
        try {
            server = new ServerSocket(port);
            log.info(">>>>>>>>>TimeServer is start on port :{}", port);
            Socket socket = null;
            //无限轮询
            while (true) {
                //没有客户端接入时 阻塞在此处
                Thread.sleep(1000);
                //有客户端连接时 接收连接 继续处理
                socket = server.accept();
                log.info("新的连接:" + socket.getInetAddress());
                //创建一个新线程处理接受消息的逻辑
                new Thread(new TimeServerHandler(socket)).start();
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (server != null) {
                server.close();
                server = null;
                log.info("The TimeServer closed");
            }
        }
    }

}
